package com.wswy.wzcx.module;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.os.Build;
import android.os.Build.VERSION;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import com.blankj.utilcode.util.DeviceUtils;
import com.blankj.utilcode.util.NetworkUtils;
import com.blankj.utilcode.util.PhoneUtils;
import com.blankj.utilcode.util.RomUtils;
import com.blankj.utilcode.util.RomUtils.RomInfo;
import com.blankj.utilcode.util.SPUtils;
import com.che.libcommon.api.ApiOptionalResultObserver;
import com.che.libcommon.api.BaseResult;
import com.che.libcommon.utils.RxHelper;
import com.che.libcommon.utils.optional.Optional;
import com.umeng.message.PushAgent;
import com.ut.device.UTDevice;
import com.wswy.wzcx.BuildConfig;
import com.wswy.wzcx.api.Api;
import com.wswy.wzcx.model.AdConfigs;
import com.wswy.wzcx.model.AdModel;
import com.wswy.wzcx.model.DeviceMod;
import com.wswy.wzcx.model.conf.SysConf;
import com.wswy.wzcx.model.conf.SysConfMap;
import com.wswy.wzcx.model.pay.PayStyleModel;
import com.wswy.wzcx.utils.FrescoUtils;
import com.wswy.wzcx.utils.SecurityCheckerUtils;
import io.reactivex.Single;
import io.reactivex.observers.ResourceSingleObserver;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicReference;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
import timber.log.Timber;

public class GlobalConfigManager {

  public static final String SP_UUID_KEY = "_d_id";

  private static final String TAG = "GlobalConfigManager";

  private long lastReqConfTime = 0;

  private DebugConfig debugConfig = new DebugConfig();

  private Context context;

  //渠道配置
  private IFlavorConfigure flavorConfigure;

  private CityManager cityManager;


  private GlobalConfigManager(){

    debugConfig.forceHttp = SPUtils.getInstance("_wzc_t").getBoolean("debug_forceHttp",false);
    debugConfig.openLog = SPUtils.getInstance("_wzc_t").getBoolean("debug_openLog",false);

    cityManager = new CityManager();

  }

  private static AtomicReference<SysConfMap> sSysConfRef = new AtomicReference<>();

  private static AtomicReference<AdConfigs> sAdConfRef = new AtomicReference<>();

  private static List<PayStyleModel> payStyleModels = new CopyOnWriteArrayList<>();

  private static List<PayStyleModel> wzdbPayStyleModels = new CopyOnWriteArrayList<>();

  private static Set<String> hostWhitelists = new CopyOnWriteArraySet<>();
  
  static {

    //默认值

    AdConfigs configs = new AdConfigs();
    
    sAdConfRef.set(configs);

    sSysConfRef.set(new SysConfMap());

    initHosts();

  }

  private static void initHosts() {

    hostWhitelists.clear();
    hostWhitelists.add("12123.com");
    hostWhitelists.add("nbajordan.cn");
    hostWhitelists.add("zqwzc.cn");
    hostWhitelists.add("zqwzc.com");

  }

  private static class InstanceHolder {
    private static final GlobalConfigManager INSTANCE = new GlobalConfigManager();
  }

  public static GlobalConfigManager getInstance(){
    return InstanceHolder.INSTANCE;
  }


  public void init(Context context){
    this.context = context;
    loadProvinceList();
    loadConfig();
  }


  private void loadProvinceList(){

    Single.fromCallable(new Callable<Boolean>() {
      @Override
      public Boolean call() throws Exception {

        cityManager.load();

        return true;
      }
    }).compose(RxHelper.<Boolean>io2main()).subscribe(new ResourceSingleObserver<Boolean>() {
      @Override
      public void onSuccess(Boolean aBoolean) {

      }

      @Override
      public void onError(Throwable e) {

      }
    });




  }

  public @NonNull CityManager getCityManager(){
    return cityManager;
  }

  public void loadConfig(){

    //大于1分钟 请求
    if (lastReqConfTime == 0 || SystemClock.elapsedRealtime() - lastReqConfTime > 1000*60*2){

      lastReqConfTime = SystemClock.elapsedRealtime();
      new SysConfLoader(context).loader(new Function1<Optional<? extends SysConfMap>, Unit>() {
        @Override
        public Unit invoke(Optional<? extends SysConfMap> optional) {
         updateSysConfig(optional.orNull());
          return null;
        }
      });

      new AllAdConfLoader(context).loader(new Function1<Optional<? extends AdConfigs>, Unit>() {
        @Override
        public Unit invoke(Optional<? extends AdConfigs> optional) {

         updateAdConfig(optional.orNull());

          return null;
        }
      });


    }

  }

  private void updateSysConf(){

  }


  public @NonNull SysConfMap getSysConf() {
    return sSysConfRef.get();
  }

  
  public @NonNull AdConfigs getAdsConf(){
    return sAdConfRef.get();
  }

  public void updateAdConfig(AdConfigs adConfigResp){
    if (adConfigResp != null){
      sAdConfRef.set(adConfigResp);

      AdModel payAd = adConfigResp.getPayAd();
      if (payAd != null && !TextUtils.isEmpty(payAd.imgUrl)){
        FrescoUtils.asyncDownloadImage(payAd.imgUrl);
      }
    }else {
      sAdConfRef.set(new AdConfigs());
    }
  }

  private void updateSysConfig(SysConfMap sysConfMap){
    if (sysConfMap != null){

      //支付方式
      payStyleModels.clear();

      //违章代办
      wzdbPayStyleModels.clear();

      SysConf choosePayTypeConf = sysConfMap.getChoosePayTypeConf();
      if (choosePayTypeConf !=null && !TextUtils.isEmpty(choosePayTypeConf.getValue())){
        String[] split = choosePayTypeConf.getValue().split(",");
        for (String s : split) {
          for (PayStyleModel value : PayStyleModel.values()) {
            if (TextUtils.equals(value.getKey(),s)){
              payStyleModels.add(value);
              break;
            }
          }
        }
      }


      choosePayTypeConf = sysConfMap.getChooseWzdbPayTypeConf();
      if (choosePayTypeConf !=null && !TextUtils.isEmpty(choosePayTypeConf.getValue())){
        String[] split = choosePayTypeConf.getValue().split(",");
        for (String s : split) {
          for (PayStyleModel value : PayStyleModel.values()) {
            if (TextUtils.equals(value.getKey(),s)){
              wzdbPayStyleModels.add(value);
              break;
            }
          }
        }
      }else {
        //默认使用
        wzdbPayStyleModels.addAll(payStyleModels);
      }

      //h5 域名白名单
      initHosts();

      SysConf hostWhitelistConf = sysConfMap.getHostWhitelistConf();
      if (hostWhitelistConf != null && !TextUtils.isEmpty(hostWhitelistConf.getValue())){

        String[] split = hostWhitelistConf.getValue().split(",");
        for (String host : split) {
          if (!TextUtils.isEmpty(host)){
            hostWhitelists.add(host);
          }
        }

      }

      sSysConfRef.set(sysConfMap);

    }
  }


  public void reloadConfig(){
    //5分钟
    if (lastReqConfTime == 0 || SystemClock.elapsedRealtime() - lastReqConfTime > 1000*60*5) {

      lastReqConfTime = SystemClock.elapsedRealtime();

      Api.get().getSysConf().subscribe(new ApiOptionalResultObserver<SysConfMap>(){

        @Override
        protected void onApiResult(@Nullable SysConfMap sysConfMap) {
          updateSysConfig(sysConfMap);
        }

        @Override
        protected void onApiError(@Nullable BaseResult result) {

        }
      });

    }

  }


  public @NonNull List<PayStyleModel> getPayStyles(){
    return payStyleModels;
  }

  public @NonNull List<PayStyleModel> getWzdbPayStyles(){
    return wzdbPayStyleModels;
  }

  public @NonNull DebugConfig getDebugConfig() {
    return debugConfig;
  }


  /**
   * 判断是否域名白名单
   * @param host
   * @return
   */
  public boolean isWhitelistHost(String host) {
    if (TextUtils.isEmpty(host)){
      return false;
    }
    for (String hostWhitelist : hostWhitelists) {
      //简单匹配！  只匹配了后面
      if (host.endsWith(hostWhitelist)){
        return true;
      }
    }
    return false;
  }


  //渠道配置
  private synchronized void initFlavor(){
    try {
      flavorConfigure = (IFlavorConfigure) Class.forName(context.getPackageName()+".cfg.FlavorConfigure").newInstance();
    } catch (Throwable e) {
      if (BuildConfig.DEBUG){
        e.printStackTrace();
      }
    }
    if (flavorConfigure == null){
      flavorConfigure = IFlavorConfigure.DEFAULT;
    }
  }

  public @NonNull
  IFlavorConfigure getFlavorConfigure() {
    if (flavorConfigure == null){
      synchronized (GlobalConfigManager.class){
        initFlavor();
      }
    }
    return flavorConfigure;
  }


  public void loadDevice(){

    if (SPUtils.getInstance().contains(SP_UUID_KEY)){
      return;
    }

    Map<String,String> map = new HashMap<>();
    map.put("p","1");
    map.put("deviceModel", Build.MODEL);  //设备信息
    map.put("deviceManufacture",Build.MANUFACTURER);
    map.put("deviceBrand",Build.BRAND);
    map.put("deviceProduct",Build.PRODUCT);
    map.put("device",Build.DEVICE);
    map.put("deviceFingerprint",Build.FINGERPRINT);
    map.put("androidSDK", String.valueOf(VERSION.SDK_INT));
    map.put("androidId", DeviceUtils.getAndroidID());
    map.put("mac",DeviceUtils.getMacAddress());
    map.put("deviceId",PhoneUtils.getDeviceId());
    map.put("imei",PhoneUtils.getIMEI());
    map.put("imsi",PhoneUtils.getIMSI()); //运营商
    map.put("meid",PhoneUtils.getMEID());
    map.put("hasRoot", String.valueOf(SecurityCheckerUtils.hasRoot(context)));

    map.put("network",SecurityCheckerUtils.getNetWorkType());
    if (TextUtils.equals(map.get("network"),"WIFI")){
      map.put("wifiIp",NetworkUtils.getIpAddressByWifi());
      map.put("wifiGetway",NetworkUtils.getGatewayByWifi());
      map.put("wifiDhcp",NetworkUtils.getServerAddressByWifi());
      map.put("wifiSSID",SecurityCheckerUtils.getWIFISSID(context));
    }
    try {
      map.put("ur",PushAgent.getInstance(context).getRegistrationId());
    }catch (Throwable e){
      e.printStackTrace();
    }

    try {
      map.put("ut",UTDevice.getUtdid(context));
    }catch (Throwable e){
      e.printStackTrace();
    }

    try {
      RomInfo romInfo = RomUtils.getRomInfo();
      map.put("rom",romInfo.getName());
      map.put("romVersion",romInfo.getVersion());
      PackageInfo packageInfo = context.getPackageManager()
          .getPackageInfo(context.getPackageName(), 0);
      map.put("appFirstInstallTime",String.valueOf(packageInfo.firstInstallTime));
      map.put("appLastUpdateTime",String.valueOf(packageInfo.lastUpdateTime));
      map.put("pkgName",packageInfo.packageName);
    } catch (Throwable e) {
      e.printStackTrace();
    }

    for (Entry<String, String> stringStringEntry : map.entrySet()) {
      Timber.e(stringStringEntry.getKey()+":"+stringStringEntry.getValue());
    }

    Api.get().requestDevice(map).subscribe(new ApiOptionalResultObserver<DeviceMod>(){

      @Override
      protected void onApiResult(@Nullable DeviceMod deviceMod) {

        if (deviceMod != null && !TextUtils.isEmpty(deviceMod.uuid)){
          SPUtils.getInstance().put(SP_UUID_KEY,deviceMod.uuid);
        }
      }

      @Override
      protected void onApiError(@Nullable BaseResult result) {

      }
    });


  }

}
